using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml.Serialization;

namespace ShearwaterLogReader
{
    #region Enums

    public enum Units
    {
        Metric,
        Imperial
    }

    #endregion

    /// <summary>
    /// Represents all the preference options.
    /// </summary>
    public class Prefs
    {
        #region Constructors

        private Prefs()
        {
            
        }

        private static Prefs prefs;
        private static object thisLock = new object();

        public static Prefs Current
        {
            get
            {
                if (prefs == null)
                {
                    lock (thisLock)
                    {
                        prefs = new Prefs();
                    }
                }

                return prefs;
            }
        }

        #endregion

        #region Default Settings 

        // Unknown
        public bool ForceAllStops = true;
        public bool OcDeco = false;

        public double RMVDive = 17;
        public double RMVDeco = 12;

        public double StopDepthIncrement = 3;
        public double LastStopDepth = 6;
        public double StopTimeIncrement = 1;        

        public bool GfMultilevelMode = false;
        public bool RuntimeFlag = true;

        public double GfLow = 0.15;
        public double GfHigh = 0.85;
        public double GfLowBailout = 0.95;
        public double GfHighBailout = 0.95;

        public double AscentRate = -10;
        public double DescentRate = 20;

        public double SetpointDefault = 0;

        public double PPO2Max = 1.6;
        public double PPO2Min = 0.21;

        public double WarningPPO2Max = 1.4;
        public double WarningPPO2Min = 0.21;
        public double WarningPPN2SpikePercentageMin = 0.01;
        public double WarningOptimalDecoPPO2Max = 1.6;
        public double WarningOptimalDecoPPO2Min = 1.0;

        public double ReportMinStopTime = 0.5;
        public bool ReportShowStopTime = true;
        public bool ReportShowBailout = true;

        public Units Units = Units.Metric;

        // Metric
        //public double PConversion = 10;
        //public double PH2O = 0.627;
        //public double PAmb = 10;
        // Imperial
        //public double PConversion = 33.0;
        //public double PH2O = 2.041;
        //public double PAmb = 33.0;

        public string DepthShortString
        {
            get
            {
                return (this.Units == Units.Metric) ? "m" : "ft";
            }
        }

        public double PConversion
        {
            get
            {
                return (this.Units == Units.Metric) ? 10 : 33;
            }
        }

        public double PH2O
        {
            get
            {
                return (this.Units == Units.Metric) ? 0.627 : 2.041;
            }
        }

        public double PAmb
        {
            get
            {
                return (this.Units == Units.Metric) ? 10 : 33;
            }
        }

        #endregion

        #region Static Methods

        /// <summary>
        /// Serialises the Prefs singleton to the output stream. 
        /// </summary>
        /// <param name="output"></param>
        public static void Serialize(Stream output)
        {
            XmlSerializer s = new XmlSerializer(typeof(Prefs));

            // To write to a file, create a StreamWriter object.
            StreamWriter writer = new StreamWriter(output);

            s.Serialize(writer, Prefs.Current);
        }

        /// <summary>
        /// Instantiates an Prefs singleton from XML.
        /// </summary>
        /// <param name="input"></param>
        public static void Deserialize(Stream input)
        {
            XmlSerializer s = new XmlSerializer(typeof(Prefs));

            lock (thisLock)
            {
                Prefs.prefs = (Prefs)s.Deserialize(input);
            }
        }

        public static void Reset()
        {
            lock (thisLock)
            {
                Prefs.prefs = new Prefs();
            }
        }

        #endregion
    }
}
